<template>
	<view class="long-press-container" @touchstart="handleTouchStart" @touchmove="handleTouchMove"
		@touchend="handleTouchEnd">
		<!-- 触发区域 -->
		<view class="trigger-area" ref="triggerArea">
			<slot></slot>
		</view>

		<!-- 提示框主体 -->
		<view v-if="showTooltip" class="tooltip" :class="['tooltip-' + tooltipPosition, tooltipClass]"
			:style="[tooltipStyle, customStyle]">
			{{ tooltipText }}
		</view>

		<!-- 隐藏的测量元素 -->
		<view class="tooltip temp-measure" ref="measureElement" :style="{ 
            visibility: 'hidden',
            position: 'fixed',
            left: '-9999px',
            top: '-9999px',
            width: autoWidth ? 'auto' : computedMaxWidth
          }">
			{{ tooltipText }}
		</view>
	</view>
</template>

<script>
	export default {
		name: 'LongPressTooltip',
		props: {
			// 提示文本
			tooltipText: {
				type: String,
				default: '长按查看说明'
			},
			// 长按触发时间（毫秒）
			longPressDuration: {
				type: Number,
				default: 500
			},
			// 最大宽度（支持数字rpx/百分比）
			maxWidth: {
				type: [Number, String],
				default: '80vw'
			},
			// 是否自动宽度模式（根据内容自适应）
			autoWidth: {
				type: Boolean,
				default: true
			},
			// 自定义样式类名
			customClass: {
				type: String,
				default: ''
			},
			// 自定义内联样式
			customStyle: {
				type: Object,
				default: () => ({})
			}
		},
		data() {
			return {
				showTooltip: false,
				tooltipPosition: 'top',
				tooltipStyle: {},
				timer: null,
				triggerRect: {},
				contentWidth: 0
			}
		},
		computed: {
			// 处理maxWidth单位转换
			computedMaxWidth() {
				if (typeof this.maxWidth === 'number') {
					return `${this.maxWidth}rpx`
				}
				return this.maxWidth
			},
			// 合并样式类名
			tooltipClass() {
				return [
					this.customClass,
					{
						'auto-width': this.autoWidth
					}
				]
			}
		},
		mounted() {
			this.initMeasureElement()
		},
		methods: {
			// 初始化测量元素
			initMeasureElement() {
				const query = uni.createSelectorQuery().in(this)
				query.select('.temp-measure').boundingClientRect(data => {
					if (data) this.contentWidth = data.width
				}).exec()
			},

			// 处理触摸开始
			async handleTouchStart(e) {
				// 获取触发元素位置
				const query = uni.createSelectorQuery().in(this)
				query.select('.trigger-area').boundingClientRect(data => {
					this.triggerRect = data
				}).exec()

				// 设置长按定时器
				this.timer = setTimeout(async () => {
					await this.showTooltipAtBestPosition(e)
				}, this.longPressDuration)
			},
			
			// 智能选择最佳显示位置
			async showTooltipAtBestPosition(e) {
				// 获取屏幕信息
				const sysInfo = uni.getSystemInfoSync()
				const screenWidth = sysInfo.screenWidth
				const screenHeight = sysInfo.screenHeight
				const touch = e.touches[0]
				
				// 获取提示框尺寸（预估）
				const tooltipWidth = Math.min(this.contentWidth + 48, screenWidth * 0.8) // 48是padding总和
				const tooltipHeight = 80 // 预估高度，增加一些预留空间
				
				// 计算各个方向的可用空间
				const spaceTop = touch.clientY
				const spaceBottom = screenHeight - touch.clientY  
				const spaceLeft = touch.clientX
				const spaceRight = screenWidth - touch.clientX
				
				// 优先级：上 > 下 > 左 > 右
				let position = 'top'
				let positionStyle = {}
				
				// 1. 优先尝试上方
				if (spaceTop >= tooltipHeight + 20) {
					position = 'top'
					positionStyle = this.calculateTopPosition(touch, tooltipWidth, tooltipHeight, screenWidth)
				}
				// 2. 尝试下方
				else if (spaceBottom >= tooltipHeight + 20) {
					position = 'bottom'
					positionStyle = this.calculateBottomPosition(touch, tooltipWidth, tooltipHeight, screenWidth)
				}
				// 3. 尝试左侧
				else if (spaceLeft >= tooltipWidth + 20) {
					position = 'left'
					positionStyle = this.calculateLeftPosition(touch, tooltipWidth, tooltipHeight, screenHeight)
				}
				// 4. 最后尝试右侧
				else if (spaceRight >= tooltipWidth + 20) {
					position = 'right'
					positionStyle = this.calculateRightPosition(touch, tooltipWidth, tooltipHeight, screenHeight)
				}
				// 5. 空间都不够，强制显示在上方（可能会被截断）
				else {
					position = 'top'
					positionStyle = this.calculateTopPosition(touch, tooltipWidth, tooltipHeight, screenWidth, true)
				}
				
				this.tooltipPosition = position
				this.tooltipStyle = {
					...positionStyle,
					maxWidth: this.computedMaxWidth,
					width: this.autoWidth ? 'auto' : this.computedMaxWidth
				}
				
				this.showTooltip = true
			},
			
			// 计算上方位置
			calculateTopPosition(touch, tooltipWidth, tooltipHeight, screenWidth, force = false) {
				let left = touch.clientX - tooltipWidth / 2
				const margin = 20
				
				// 确保不超出屏幕边界
				if (left < margin) left = margin
				if (left + tooltipWidth > screenWidth - margin) left = screenWidth - tooltipWidth - margin
				
				return {
					top: force ? `${margin}px` : `${touch.clientY - 20}px`, // 固定距离点击位置20px
					left: `${left}px`
				}
			},
			
			// 计算下方位置  
			calculateBottomPosition(touch, tooltipWidth, tooltipHeight, screenWidth) {
				let left = touch.clientX - tooltipWidth / 2
				const margin = 20
				
				// 确保不超出屏幕边界
				if (left < margin) left = margin
				if (left + tooltipWidth > screenWidth - margin) left = screenWidth - tooltipWidth - margin
				
				return {
					top: `${touch.clientY + 20}px`, // 距离点击位置20px
					left: `${left}px`
				}
			},
			
			// 计算左侧位置
			calculateLeftPosition(touch, tooltipWidth, tooltipHeight, screenHeight) {
				let top = touch.clientY - 40 // 让提示框中心与点击位置大致对齐
				const margin = 20
				
				// 确保不超出屏幕边界
				if (top < margin) top = margin
				if (top + tooltipHeight > screenHeight - margin) top = screenHeight - tooltipHeight - margin
				
				return {
					top: `${top}px`,
					left: `${touch.clientX - tooltipWidth - 20}px` // 距离点击位置20px
				}
			},
			
			// 计算右侧位置
			calculateRightPosition(touch, tooltipWidth, tooltipHeight, screenHeight) {
				let top = touch.clientY - 40 // 让提示框中心与点击位置大致对齐
				const margin = 20
				
				// 确保不超出屏幕边界
				if (top < margin) top = margin
				if (top + tooltipHeight > screenHeight - margin) top = screenHeight - tooltipHeight - margin
				
				return {
					top: `${top}px`,
					left: `${touch.clientX + 20}px` // 距离点击位置20px
				}
			},

			// 处理触摸移动
			handleTouchMove() {
				if (this.timer) {
					clearTimeout(this.timer)
					this.timer = null
				}
				// this.showTooltip = false
			},

			// 处理触摸结束
			handleTouchEnd() {
				if (this.timer) {
					clearTimeout(this.timer)
					this.timer = null
				}
				this.showTooltip = false
			}
		}
	}
</script>

<style lang="scss" scoped>
	.long-press-container {
		width: 100%;
		position: relative;
		display: inline-block;
	}

	.trigger-area {
		/* padding: 20rpx;
		background-color: #f0f0f0;
		border-radius: 8rpx; */
		width: 100%;
		// white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.tooltip {
		position: fixed;
		background: rgba(0, 0, 0, 0.8);
		color: #fff;
		padding: 16rpx 24rpx;
		border-radius: 12rpx;
		font-size: 28rpx;
		line-height: 1.4;
		white-space: normal;
		word-break: break-word;
		z-index: 99999;
		pointer-events: none;
		transition: opacity 0.3s ease;
		max-width: 80vw;
		box-sizing: border-box;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3);
		backdrop-filter: blur(4rpx);
	}

	.tooltip.tooltip-top {
		transform: translateY(-100%);
	}

	.tooltip.tooltip-bottom {
		transform: translateY(0);
	}

	.tooltip.tooltip-left {
		transform: translateX(-100%);
	}

	.tooltip.tooltip-right {
		transform: translateX(0);
	}

	.tooltip.auto-width {
		white-space: nowrap;
		min-width: 120rpx;
	}

	.temp-measure {
		padding: 12rpx 24rpx;
		font-size: 28rpx;
		word-break: break-word;
		white-space: pre-wrap;
	}
</style>